#!/usr/bin/env python3
"""
PLOOP数据处理器（修复版） - 基于IDA Pro分析的SET2D算法实现
处理带FRADIUS的顶点数据，生成平滑截面profile
"""

import math
import re
from typing import List, Tuple, Optional
from dataclasses import dataclass

@dataclass
class Vertex:
    """顶点数据结构"""
    x: float
    y: float
    z: float
    fradius: Optional[float] = None
    
    def __str__(self):
        if self.fradius:
            return f"({self.x:.2f}, {self.y:.2f}, {self.z:.2f}, FRAD:{self.fradius:.2f})"
        return f"({self.x:.2f}, {self.y:.2f}, {self.z:.2f})"

@dataclass
class PLoop:
    """PLOOP数据结构"""
    name: str
    height: float
    vertices: List[Vertex]
    
    def __str__(self):
        return f"PLOOP {self.name}: H={self.height}, {len(self.vertices)} vertices"

class PLoopProcessor:
    """PLOOP处理器 - 实现SET2D算法"""
    
    def __init__(self, tolerance: float = 1.0):
        self.tolerance = tolerance
    
    def parse_position(self, pos_str: str) -> Tuple[float, float, float]:
        """解析位置字符串 POS E 0mm N 2949.5mm U 0mm"""
        x, y, z = 0.0, 0.0, 0.0
        
        # 解析E/W方向（X轴）
        e_match = re.search(r'E\s+([\d.-]+)mm', pos_str)
        w_match = re.search(r'W\s+([\d.-]+)mm', pos_str)
        if e_match:
            x = float(e_match.group(1))
        elif w_match:
            x = -float(w_match.group(1))
        
        # 解析N/S方向（Y轴）
        n_match = re.search(r'N\s+([\d.-]+)mm', pos_str)
        s_match = re.search(r'S\s+([\d.-]+)mm', pos_str)
        if n_match:
            y = float(n_match.group(1))
        elif s_match:
            y = -float(s_match.group(1))
        
        # 解析U方向（Z轴）
        u_match = re.search(r'U\s+([\d.-]+)mm', pos_str)
        if u_match:
            z = float(u_match.group(1))
        
        return x, y, z
    
    def parse_file(self, content: str) -> List[PLoop]:
        """解析PLOOP文件"""
        ploops = []
        lines = content.split('\n')
        
        framework_name = "Unknown"
        current_ploop = None
        current_vertex = None
        end_count = 0  # 追踪END的嵌套层级
        
        for line_num, line in enumerate(lines, 1):
            line = line.strip()
            
            # 检测FRMWORK名称
            if line.startswith('NEW FRMWORK'):
                parts = line.split()
                framework_name = parts[2] if len(parts) > 2 else f"Framework_{line_num}"
                print(f"发现FRMWORK: {framework_name}")
            
            # 检测PLOOP开始
            elif line == 'NEW PLOOP':
                current_ploop = {'name': framework_name, 'vertices': [], 'height': 0.0}
                end_count = 0
                print(f"  开始PLOOP: {framework_name}")
            
            # 检测PLOOP高度
            elif line.startswith('HEIG') and current_ploop is not None:
                height_match = re.search(r'HEIG\s+([\d.-]+)mm', line)
                if height_match:
                    current_ploop['height'] = float(height_match.group(1))
                    print(f"    高度: {current_ploop['height']}mm")
            
            # 检测顶点开始
            elif line == 'NEW PAVERT' and current_ploop is not None:
                current_vertex = {'x': 0.0, 'y': 0.0, 'z': 0.0, 'fradius': None}
            
            # 检测位置信息
            elif line.startswith('POS') and current_vertex is not None:
                x, y, z = self.parse_position(line)
                current_vertex.update({'x': x, 'y': y, 'z': z})
            
            # 检测圆角半径
            elif line.startswith('FRAD') and current_vertex is not None:
                frad_match = re.search(r'FRAD\s+([\d.-]+)mm', line)
                if frad_match:
                    current_vertex['fradius'] = float(frad_match.group(1))
                    print(f"      发现FRAD: {current_vertex['fradius']}mm")
            
            # 检测END
            elif line == 'END':
                if current_vertex is not None:
                    # 顶点结束
                    vertex = Vertex(
                        x=current_vertex['x'],
                        y=current_vertex['y'], 
                        z=current_vertex['z'],
                        fradius=current_vertex['fradius']
                    )
                    current_ploop['vertices'].append(vertex)
                    print(f"      添加顶点: {vertex}")
                    current_vertex = None
                elif current_ploop is not None:
                    # 可能是PLOOP结束的END
                    end_count += 1
                    if end_count >= 3:  # 通常PLOOP有多个嵌套的END
                        # 保存当前PLOOP
                        if len(current_ploop['vertices']) > 0:
                            ploop = PLoop(
                                name=current_ploop['name'],
                                height=current_ploop['height'],
                                vertices=current_ploop['vertices']
                            )
                            ploops.append(ploop)
                            print(f"  完成PLOOP: {ploop}")
                        current_ploop = None
                        end_count = 0
        
        return ploops
    
    def calculate_fillet_arc_info(self, prev_vertex: Vertex, vertex: Vertex, next_vertex: Vertex) -> dict:
        """计算圆弧信息，返回用于SVG绘制的数据"""
        if vertex.fradius is None or vertex.fradius <= 0:
            return None

        # 计算前后边的向量
        v1_x = vertex.x - prev_vertex.x
        v1_y = vertex.y - prev_vertex.y
        v2_x = next_vertex.x - vertex.x
        v2_y = next_vertex.y - vertex.y

        # 标准化向量
        len1 = math.sqrt(v1_x*v1_x + v1_y*v1_y)
        len2 = math.sqrt(v2_x*v2_x + v2_y*v2_y)

        if len1 < self.tolerance or len2 < self.tolerance:
            return None

        v1_x /= len1
        v1_y /= len1
        v2_x /= len2
        v2_y /= len2

        # 计算夹角
        dot_product = v1_x * v2_x + v1_y * v2_y
        dot_product = max(-1.0, min(1.0, dot_product))  # 限制范围

        angle = math.acos(abs(dot_product))
        half_angle = angle / 2.0

        if half_angle < 0.001:  # 角度太小，跳过圆角
            return None

        # 计算到切点的距离
        tan_half = math.tan(half_angle)
        if tan_half < 0.001:  # 使用更小的阈值，防止除零错误
            return None

        dist_to_tangent = vertex.fradius / tan_half

        # 限制切点距离，防止超出边长
        max_dist1 = len1 * 0.9
        max_dist2 = len2 * 0.9
        dist_to_tangent = min(dist_to_tangent, max_dist1, max_dist2)

        # 计算两个切点
        tangent1_x = vertex.x - v1_x * dist_to_tangent
        tangent1_y = vertex.y - v1_y * dist_to_tangent
        tangent2_x = vertex.x + v2_x * dist_to_tangent
        tangent2_y = vertex.y + v2_y * dist_to_tangent

        # 计算圆心（角平分线方向）
        bisector_x = v1_x + v2_x
        bisector_y = v1_y + v2_y
        bisector_len = math.sqrt(bisector_x*bisector_x + bisector_y*bisector_y)

        if bisector_len < self.tolerance:
            return None

        bisector_x /= bisector_len
        bisector_y /= bisector_len

        # 判断凸凹性（叉积）
        cross_product = v1_x * v2_y - v1_y * v2_x
        radius_sign = 1.0 if cross_product > 0 else -1.0

        center_dist = vertex.fradius / math.sin(half_angle)
        center_x = vertex.x + bisector_x * center_dist * radius_sign
        center_y = vertex.y + bisector_y * center_dist * radius_sign

        # 计算扫描角度
        angle1 = math.atan2(tangent1_y - center_y, tangent1_x - center_x)
        angle2 = math.atan2(tangent2_y - center_y, tangent2_x - center_x)

        # 确定扫描方向
        angle_diff = angle2 - angle1
        if abs(angle_diff) > math.pi:
            if angle_diff > 0:
                angle_diff -= 2 * math.pi
            else:
                angle_diff += 2 * math.pi

        # 判断是否为大弧（large-arc-flag）
        large_arc = abs(angle_diff) > math.pi

        # 判断扫描方向（sweep-flag）
        sweep_flag = angle_diff > 0

        return {
            'center': (center_x, center_y),
            'radius': vertex.fradius,
            'start_point': (tangent1_x, tangent1_y),
            'end_point': (tangent2_x, tangent2_y),
            'large_arc': large_arc,
            'sweep_flag': sweep_flag,
            'angle_diff': angle_diff,
            'original_vertex': vertex
        }

    def calculate_fillet_arc(self, prev_vertex: Vertex, vertex: Vertex, next_vertex: Vertex) -> List[Vertex]:
        """计算内切圆弧顶点 - 简化版，主要用于顶点处理"""
        arc_info = self.calculate_fillet_arc_info(prev_vertex, vertex, next_vertex)
        if arc_info is None:
            return [vertex]

        # 返回切点，用于多边形顶点处理
        # 第一个切点保留FRADIUS信息，用于SVG圆弧绘制
        start_vertex = Vertex(arc_info['start_point'][0], arc_info['start_point'][1], vertex.z, vertex.fradius)
        end_vertex = Vertex(arc_info['end_point'][0], arc_info['end_point'][1], vertex.z)

        print(f"    圆弧处理: 原始顶点({vertex.x:.2f}, {vertex.y:.2f}) FRADIUS:{vertex.fradius:.2f} → 起点({start_vertex.x:.2f}, {start_vertex.y:.2f}) FRADIUS:{start_vertex.fradius:.2f}")

        return [start_vertex, end_vertex]
    
    def process_ploop(self, ploop: PLoop) -> List[Vertex]:
        """处理PLOOP，生成最终的profile顶点"""
        if len(ploop.vertices) < 3:
            return ploop.vertices
        
        processed_vertices = []
        n = len(ploop.vertices)
        
        # 移除重复的相邻顶点
        unique_vertices = []
        for i, v in enumerate(ploop.vertices):
            if i == 0 or (abs(v.x - ploop.vertices[i-1].x) > self.tolerance or 
                         abs(v.y - ploop.vertices[i-1].y) > self.tolerance):
                unique_vertices.append(v)
        
        vertices = unique_vertices
        n = len(vertices)
        
        # 确保首尾闭合
        if n > 2 and (abs(vertices[0].x - vertices[-1].x) > self.tolerance or 
                      abs(vertices[0].y - vertices[-1].y) > self.tolerance):
            vertices.append(vertices[0])  # 闭合多边形
            n = len(vertices)
        
        for i in range(n - 1):  # 跳过最后一个重复点
            current = vertices[i]
            prev_vertex = vertices[i - 1] if i > 0 else vertices[n - 2]
            next_vertex = vertices[i + 1]

            # 只对有FRADIUS的顶点处理圆角
            if current.fradius and current.fradius > 0:
                arc_vertices = self.calculate_fillet_arc(prev_vertex, current, next_vertex)
                processed_vertices.extend(arc_vertices)
            else:
                # 普通顶点直接添加
                processed_vertices.append(current)
        
        # 最终清理：移除所有重复顶点（不仅仅是相邻的）
        final_vertices = []
        for vertex in processed_vertices:
            # 检查是否与已有顶点重复
            is_duplicate = False
            for existing in final_vertices:
                if (abs(vertex.x - existing.x) <= self.tolerance and
                    abs(vertex.y - existing.y) <= self.tolerance):
                    is_duplicate = True
                    break

            if not is_duplicate:
                final_vertices.append(vertex)

        # AVEVA风格的共线顶点裁剪 (colinear chop)
        final_vertices = self.remove_collinear_vertices(final_vertices)

        # 额外的几何优化：移除几乎水平/垂直线上的冗余顶点
        final_vertices = self.remove_near_horizontal_vertical_redundant_vertices(final_vertices)

        return final_vertices

    def remove_collinear_vertices(self, vertices: List[Vertex]) -> List[Vertex]:
        """AVEVA风格的共线顶点处理系统"""
        if len(vertices) < 3:
            return vertices

        print("  开始AVEVA风格共线处理...")
        initial_count = len(vertices)

        # 第一步：共线顶点裁剪 (colinear chop)
        print(f"    步骤1: 共线顶点裁剪 (输入: {len(vertices)} 个顶点)")
        vertices = self.colinear_chop(vertices)

        # 第二步：共线顶点合并 (colinear merge)
        print(f"    步骤2: 共线顶点合并 (输入: {len(vertices)} 个顶点)")
        vertices = self.colinear_merge(vertices)

        # 第三步：直线连接优化 (straight concatenation)
        print(f"    步骤3: 直线连接优化 (输入: {len(vertices)} 个顶点)")
        vertices = self.straight_concatenation(vertices)

        final_count = len(vertices)
        total_removed = initial_count - final_count
        print(f"  AVEVA共线处理完成: {initial_count} → {final_count} 个顶点 (移除 {total_removed} 个)")
        return vertices

    def colinear_chop(self, vertices: List[Vertex]) -> List[Vertex]:
        """第一步：共线顶点裁剪 - 移除共线的中间顶点"""
        if len(vertices) < 3:
            return vertices

        cleaned_vertices = []
        n = len(vertices)
        removed_count = 0

        for i in range(n):
            current = vertices[i]
            prev_vertex = vertices[i - 1] if i > 0 else vertices[n - 1]
            next_vertex = vertices[i + 1] if i < n - 1 else vertices[0]

            # 检查三点是否共线
            if not self.is_collinear_strict(prev_vertex, current, next_vertex):
                cleaned_vertices.append(current)
            else:
                print(f"    共线裁剪: 移除顶点 ({current.x:.2f}, {current.y:.2f})")
                removed_count += 1

        print(f"    共线裁剪完成，移除 {removed_count} 个顶点")
        return cleaned_vertices

    def colinear_merge(self, vertices: List[Vertex]) -> List[Vertex]:
        """第二步：共线顶点合并 - 合并距离很近的共线顶点"""
        if len(vertices) < 3:
            return vertices

        merged_vertices = []
        n = len(vertices)
        i = 0
        merged_count = 0

        while i < n:
            current = vertices[i]

            # 查找可以合并的连续共线顶点
            merge_group = [current]
            j = i + 1

            while j < n:
                next_vertex = vertices[j]

                # 检查是否可以合并（距离很近且方向一致）
                if self.can_merge_vertices(current, next_vertex):
                    merge_group.append(next_vertex)
                    j += 1
                else:
                    break

            # 如果有多个顶点可以合并，选择最优的代表点
            if len(merge_group) > 1:
                representative = self.select_representative_vertex(merge_group)
                merged_vertices.append(representative)
                merged_count += len(merge_group) - 1
                print(f"    共线合并: 合并 {len(merge_group)} 个顶点到 ({representative.x:.2f}, {representative.y:.2f})")
            else:
                merged_vertices.append(current)

            i = j

        print(f"    共线合并完成，合并 {merged_count} 个顶点")
        return merged_vertices

    def is_collinear(self, p1: Vertex, p2: Vertex, p3: Vertex) -> bool:
        """检查三个点是否共线（使用叉积）"""
        # 计算向量
        v1_x = p2.x - p1.x
        v1_y = p2.y - p1.y
        v2_x = p3.x - p2.x
        v2_y = p3.y - p2.y

        # 计算叉积
        cross_product = v1_x * v2_y - v1_y * v2_x

        # 计算向量长度
        len1 = math.sqrt(v1_x*v1_x + v1_y*v1_y)
        len2 = math.sqrt(v2_x*v2_x + v2_y*v2_y)

        # 如果任一边长度为0，不认为共线（避免删除重要顶点）
        if len1 < self.tolerance or len2 < self.tolerance:
            return False

        # 使用相对面积容差：叉积 / (len1 * len2) < tolerance
        # 这相当于检查角度是否接近0或180度
        relative_area = abs(cross_product) / (len1 * len2)

        # 使用更小的容差，只移除真正共线的顶点
        collinear_tolerance = 0.001  # 0.1% 的角度容差

        return relative_area < collinear_tolerance

    def is_collinear_strict(self, p1: Vertex, p2: Vertex, p3: Vertex) -> bool:
        """严格的共线检测，用于裁剪"""
        # 计算向量
        v1_x = p2.x - p1.x
        v1_y = p2.y - p1.y
        v2_x = p3.x - p2.x
        v2_y = p3.y - p2.y

        # 计算叉积
        cross_product = v1_x * v2_y - v1_y * v2_x

        # 计算向量长度
        len1 = math.sqrt(v1_x*v1_x + v1_y*v1_y)
        len2 = math.sqrt(v2_x*v2_x + v2_y*v2_y)

        # 如果任一边长度为0，不认为共线（避免删除重要顶点）
        if len1 < self.tolerance or len2 < self.tolerance:
            return False

        # 使用更严格的容差进行共线检测
        relative_area = abs(cross_product) / (len1 * len2)
        strict_tolerance = 0.001  # 0.1% 的角度容差，适中的严格程度

        return relative_area < strict_tolerance

    def can_merge_vertices(self, v1: Vertex, v2: Vertex) -> bool:
        """检查两个顶点是否可以合并"""
        # 距离检查
        distance = math.sqrt((v1.x - v2.x)**2 + (v1.y - v2.y)**2)
        if distance > self.tolerance * 2:  # 使用2倍容差
            return False

        # 如果距离很近，可以合并
        return True

    def select_representative_vertex(self, vertices: List[Vertex]) -> Vertex:
        """从一组可合并的顶点中选择最优的代表点"""
        if len(vertices) == 1:
            return vertices[0]

        # 计算质心作为代表点
        sum_x = sum(v.x for v in vertices)
        sum_y = sum(v.y for v in vertices)
        avg_x = sum_x / len(vertices)
        avg_y = sum_y / len(vertices)

        # 创建新的代表顶点
        return Vertex(avg_x, avg_y, vertices[0].z)

    def straight_concatenation(self, vertices: List[Vertex]) -> List[Vertex]:
        """第三步：直线连接优化 - 优化连续的短直线段"""
        if len(vertices) < 4:
            return vertices

        optimized_vertices = []
        n = len(vertices)
        i = 0
        concatenated_count = 0

        while i < n:
            current = vertices[i]

            # 查找可以连接的连续直线段
            straight_group = [current]
            j = i + 1

            while j < n - 1:  # 保留最后一个顶点
                next_vertex = vertices[j]
                next_next = vertices[j + 1] if j + 1 < n else vertices[0]

                # 检查是否形成直线段
                if self.forms_straight_line(current, next_vertex, next_next):
                    straight_group.append(next_vertex)
                    j += 1
                else:
                    break

            # 如果有多个顶点形成直线，只保留端点
            if len(straight_group) > 2:
                optimized_vertices.append(straight_group[0])  # 起点
                optimized_vertices.append(straight_group[-1])  # 终点
                concatenated_count += len(straight_group) - 2
                print(f"    直线连接: 连接 {len(straight_group)} 个顶点")
            else:
                optimized_vertices.append(current)

            i = j

        print(f"    直线连接完成，优化 {concatenated_count} 个顶点")
        return optimized_vertices

    def forms_straight_line(self, p1: Vertex, p2: Vertex, p3: Vertex) -> bool:
        """检查三个点是否形成直线段（用于连接优化）"""
        return self.is_collinear_strict(p1, p2, p3)

    def remove_near_horizontal_vertical_redundant_vertices(self, vertices: List[Vertex]) -> List[Vertex]:
        """移除几乎水平/垂直线上的冗余顶点"""
        if len(vertices) < 3:
            return vertices

        cleaned_vertices = []
        n = len(vertices)

        for i in range(n):
            current = vertices[i]
            prev_vertex = vertices[i - 1] if i > 0 else vertices[n - 1]
            next_vertex = vertices[i + 1] if i < n - 1 else vertices[0]

            # 检查是否在几乎水平的线上
            if (abs(prev_vertex.y - current.y) < self.tolerance and
                abs(current.y - next_vertex.y) < self.tolerance):
                # 三个点几乎在同一水平线上，检查中间点是否可以省略
                if (prev_vertex.x < current.x < next_vertex.x or
                    next_vertex.x < current.x < prev_vertex.x):
                    print(f"    水平线优化: 移除顶点 ({current.x:.2f}, {current.y:.2f})")
                    continue

            # 检查是否在几乎垂直的线上
            if (abs(prev_vertex.x - current.x) < self.tolerance and
                abs(current.x - next_vertex.x) < self.tolerance):
                # 三个点几乎在同一垂直线上，检查中间点是否可以省略
                if (prev_vertex.y < current.y < next_vertex.y or
                    next_vertex.y < current.y < prev_vertex.y):
                    print(f"    垂直线优化: 移除顶点 ({current.x:.2f}, {current.y:.2f})")
                    continue

            cleaned_vertices.append(current)

        return cleaned_vertices

    def calculate_label_position(self, x: float, y: float, vertex_idx: int, all_positions: list) -> tuple:
        """计算标注位置，避免与其他顶点重叠"""
        # 默认偏移位置（右上角）
        offset_x, offset_y = 8, -8

        # 检查是否与其他顶点太接近
        min_distance = 25  # 最小距离阈值

        # 尝试不同的标注位置
        positions_to_try = [
            (8, -8),    # 右上
            (-20, -8),  # 左上
            (8, 15),    # 右下
            (-20, 15),  # 左下
            (0, -20),   # 正上
            (0, 25),    # 正下
            (15, 0),    # 正右
            (-25, 0),   # 正左
        ]

        for offset_x, offset_y in positions_to_try:
            label_x = x + offset_x
            label_y = y + offset_y

            # 检查是否与其他顶点冲突
            conflict = False
            for other_x, other_y, other_idx in all_positions:
                if other_idx != vertex_idx:
                    distance = math.sqrt((label_x - other_x)**2 + (label_y - other_y)**2)
                    if distance < min_distance:
                        conflict = True
                        break

            if not conflict:
                return label_x, label_y

        # 如果所有位置都冲突，使用默认位置
        return x + 8, y - 8

    def map_fradius_to_processed_vertices(self, original_vertices: List[Vertex], processed_vertices: List[Vertex]) -> List[Vertex]:
        """将原始顶点的FRADIUS信息映射到处理后的顶点"""
        # 创建处理后顶点的副本
        mapped_vertices = []

        print(f"  开始FRADIUS映射: 原始{len(original_vertices)}个顶点 → 处理后{len(processed_vertices)}个顶点")

        for i, processed_vertex in enumerate(processed_vertices):
            # 在原始顶点中查找匹配的FRADIUS信息
            fradius = None
            best_match = None
            min_distance = float('inf')

            for j, original_vertex in enumerate(original_vertices):
                # 计算距离
                distance = ((processed_vertex.x - original_vertex.x)**2 +
                           (processed_vertex.y - original_vertex.y)**2)**0.5

                # 如果距离在容差范围内且有FRADIUS信息
                if distance <= self.tolerance and original_vertex.fradius:
                    if distance < min_distance:
                        min_distance = distance
                        fradius = original_vertex.fradius
                        best_match = j

            if fradius:
                print(f"    映射成功: 处理后顶点[{i}] ({processed_vertex.x:.2f}, {processed_vertex.y:.2f}) ← 原始顶点[{best_match}] FRADIUS:{fradius:.2f}mm")

            # 创建新的顶点，保留FRADIUS信息
            new_vertex = Vertex(processed_vertex.x, processed_vertex.y, processed_vertex.z, fradius)
            mapped_vertices.append(new_vertex)

        fradius_count = sum(1 for v in mapped_vertices if v.fradius)
        print(f"  FRADIUS映射完成: 成功映射{fradius_count}个圆弧顶点")
        return mapped_vertices

    def generate_profile_report(self, ploop: PLoop, processed_vertices: List[Vertex]) -> str:
        """生成详细的profile报告"""
        report = []
        report.append("=" * 80)
        report.append(f"PLOOP PROFILE REPORT: {ploop.name}")
        report.append("=" * 80)
        report.append(f"Height: {ploop.height}mm")
        report.append(f"Original vertices: {len(ploop.vertices)}")
        report.append(f"Processed vertices: {len(processed_vertices)}")
        report.append("")
        
        # 统计圆角信息
        fradius_count = sum(1 for v in ploop.vertices if v.fradius is not None)
        if fradius_count > 0:
            report.append(f"FRADIUS处理: {fradius_count} 个圆角顶点")
            for i, v in enumerate(ploop.vertices):
                if v.fradius:
                    report.append(f"  顶点[{i}]: 圆角半径 {v.fradius}mm")
        report.append("")
        
        # 原始顶点列表
        report.append("原始顶点坐标:")
        for i, v in enumerate(ploop.vertices):
            report.append(f"  [{i:2d}] {v}")
        report.append("")
        
        # 处理后的顶点列表
        report.append("最终Profile顶点坐标:")
        for i, v in enumerate(processed_vertices):
            report.append(f"  [{i:3d}] {v}")
        report.append("")
        
        # 计算几何信息
        if processed_vertices:
            x_coords = [v.x for v in processed_vertices]
            y_coords = [v.y for v in processed_vertices]
            
            bounds = {
                'min_x': min(x_coords),
                'max_x': max(x_coords),
                'min_y': min(y_coords), 
                'max_y': max(y_coords),
                'width': max(x_coords) - min(x_coords),
                'height': max(y_coords) - min(y_coords)
            }
            
            report.append("几何边界信息:")
            report.append(f"  X范围: {bounds['min_x']:.2f} ~ {bounds['max_x']:.2f} mm (宽度: {bounds['width']:.2f}mm)")
            report.append(f"  Y范围: {bounds['min_y']:.2f} ~ {bounds['max_y']:.2f} mm (高度: {bounds['height']:.2f}mm)")
        
        report.append("=" * 80)
        return "\n".join(report)

    def generate_svg_with_arcs(self, ploop: PLoop, processed_vertices: List[Vertex], filename: str = None) -> str:
        """生成带真实圆弧的SVG可视化"""
        if not processed_vertices:
            return ""



        # 使用原始顶点来计算边界，确保包含所有数据
        all_vertices = ploop.vertices
        x_coords = [v.x for v in all_vertices]
        y_coords = [v.y for v in all_vertices]

        min_x, max_x = min(x_coords), max(x_coords)
        min_y, max_y = min(y_coords), max(y_coords)

        # 固定SVG尺寸
        svg_width = 1000
        svg_height = 800
        margin = 60

        # 计算缩放比例
        data_width = max_x - min_x
        data_height = max_y - min_y

        if data_width == 0:
            data_width = 1
        if data_height == 0:
            data_height = 1

        scale_x = (svg_width - 2 * margin) / data_width
        scale_y = (svg_height - 2 * margin) / data_height
        scale = min(scale_x, scale_y)  # 保持比例

        # 转换坐标函数
        def transform_x(x):
            return margin + (x - min_x) * scale

        def transform_y(y):
            return svg_height - margin - (y - min_y) * scale  # Y轴翻转

        # SVG头部
        svg_lines = [
            f'<svg width="{svg_width}" height="{svg_height}" viewBox="0 0 {svg_width} {svg_height}" xmlns="http://www.w3.org/2000/svg">',
            # 定义箭头标记（更小的箭头）
            '<defs>',
            '  <marker id="arrowhead" markerWidth="6" markerHeight="4" refX="5" refY="2" orient="auto">',
            '    <polygon points="0 0, 6 2, 0 4" fill="#FF6600" stroke="#FF6600" stroke-width="0.5"/>',
            '  </marker>',
            '  <marker id="arrowhead-arc" markerWidth="6" markerHeight="4" refX="5" refY="2" orient="auto">',
            '    <polygon points="0 0, 6 2, 0 4" fill="#FF0066" stroke="#FF0066" stroke-width="0.5"/>',
            '  </marker>',
            '</defs>',
            f'<rect x="0" y="0" width="{svg_width}" height="{svg_height}" opacity="1" fill="#FFFFFF" stroke="none"/>',
            f'<text x="{svg_width//2}" y="25" dy="0.76em" text-anchor="middle" font-family="Arial" font-size="16" opacity="1" fill="#000000">',
            f'PLOOP Profile: {ploop.name} (高度: {ploop.height}mm, 带路径箭头标识)',
            '</text>',
        ]

        # 生成带圆弧的路径 - 使用已处理的顶点
        path_commands = []
        # 直接使用已经处理过的顶点，包含正确的顶点19
        vertices = processed_vertices
        n = len(vertices)

        print(f"  使用去重后顶点生成路径: {n} 个顶点")
        fradius_count = sum(1 for v in vertices if v.fradius)
        print(f"  包含FRADIUS顶点: {fradius_count} 个")

        # 路径应该闭合，移除错误的开放路径检测
        is_open_path = False

        # 确保闭合
        if n > 2 and (abs(vertices[0].x - vertices[-1].x) > self.tolerance or
                      abs(vertices[0].y - vertices[-1].y) > self.tolerance):
            vertices = vertices + [vertices[0]]  # 闭合多边形
            n = len(vertices)
            print(f"  添加闭合顶点: ({vertices[0].x:.2f}, {vertices[0].y:.2f})")
        else:
            print(f"  首尾顶点已经重合，无需添加闭合顶点")

        # 移动到起点
        start_x = transform_x(vertices[0].x)
        start_y = transform_y(vertices[0].y)
        path_commands.append(f"M {start_x:.2f} {start_y:.2f}")

        # 处理每个顶点
        i = 1
        while i < n:
            current = vertices[i]
            prev_vertex = vertices[i - 1]

            # 检查前一个顶点是否有FRADIUS（因为FRADIUS信息保存在圆弧起点）
            if hasattr(prev_vertex, 'fradius') and prev_vertex.fradius and prev_vertex.fradius > 0:
                # 找到圆弧的三个关键点
                if i >= 2:
                    arc_prev = vertices[i - 2]
                else:
                    arc_prev = vertices[n - 2] if n > 2 else vertices[0]

                arc_center = prev_vertex  # 有FRADIUS的顶点
                arc_next = current

                print(f"  绘制圆弧: 从({arc_prev.x:.2f}, {arc_prev.y:.2f}) 经过({arc_center.x:.2f}, {arc_center.y:.2f}) 到({arc_next.x:.2f}, {arc_next.y:.2f}) FRADIUS:{arc_center.fradius:.2f}")

                # 计算圆弧信息
                arc_info = self.calculate_fillet_arc_info(arc_prev, arc_center, arc_next)

                if arc_info:
                    # 画圆弧到下一个顶点，而不是切点
                    # 这样可以确保弧线正确连接到下一个顶点
                    end_x = transform_x(current.x)
                    end_y = transform_y(current.y)
                    radius_scaled = arc_info['radius'] * scale

                    # SVG弧命令: A rx ry x-axis-rotation large-arc-flag sweep-flag x y
                    large_arc_flag = 1 if arc_info['large_arc'] else 0
                    sweep_flag = 1 if arc_info['sweep_flag'] else 0

                    path_commands.append(f"A {radius_scaled:.2f} {radius_scaled:.2f} 0 {large_arc_flag} {sweep_flag} {end_x:.2f} {end_y:.2f}")
                    print(f"    SVG圆弧命令: A {radius_scaled:.2f} {radius_scaled:.2f} 0 {large_arc_flag} {sweep_flag} {end_x:.2f} {end_y:.2f}")

                    i += 1
                else:
                    # 如果圆弧计算失败，画直线
                    x = transform_x(current.x)
                    y = transform_y(current.y)
                    path_commands.append(f"L {x:.2f} {y:.2f}")
                    print(f"    圆弧计算失败，绘制直线到({current.x:.2f}, {current.y:.2f})")
                    i += 1
            else:
                # 普通顶点，画直线
                x = transform_x(current.x)
                y = transform_y(current.y)
                path_commands.append(f"L {x:.2f} {y:.2f}")
                i += 1

        # 根据路径类型决定是否闭合
        if not is_open_path:
            path_commands.append("Z")
        else:
            print(f"  开放路径，不添加Z命令闭合")

        # 添加主要路径
        path_data = " ".join(path_commands)
        svg_lines.append(f'<path d="{path_data}" fill="none" opacity="1" stroke="#0000FF" stroke-width="2"/>')

        # 添加顶点标记（使用处理后的顶点，避免重复）
        vertex_positions = []
        for i, vertex in enumerate(processed_vertices):
            x = transform_x(vertex.x)
            y = transform_y(vertex.y)
            vertex_positions.append((x, y, i))
            # 顶点圆圈
            svg_lines.append(f'<circle cx="{x:.0f}" cy="{y:.0f}" r="3" opacity="1" fill="#FF0000" stroke="white" stroke-width="1"/>')

        # 智能标注位置调整，避免重叠
        for i, (x, y, vertex_idx) in enumerate(vertex_positions):
            # 计算标注位置
            label_x, label_y = self.calculate_label_position(x, y, vertex_idx, vertex_positions)
            # 顶点编号
            svg_lines.append(f'<text x="{label_x:.0f}" y="{label_y:.0f}" font-family="Arial" font-size="10" font-weight="bold" fill="#000000" stroke="white" stroke-width="0.5">{vertex_idx}</text>')

        # 添加路径箭头和文字标注
        self.add_path_arrows_and_labels(svg_lines, processed_vertices, transform_x, transform_y, is_open_path)

        # 添加FRADIUS顶点特殊标记
        for vertex in ploop.vertices:
            if vertex.fradius and vertex.fradius > 0:
                x = transform_x(vertex.x)
                y = transform_y(vertex.y)
                svg_lines.append(f'<circle cx="{x:.0f}" cy="{y:.0f}" r="4" opacity="1" fill="none" stroke="#FFA500" stroke-width="2"/>')
                # 添加半径标注
                svg_lines.append(f'<text x="{x + 10:.0f}" y="{y - 10:.0f}" font-family="Arial" font-size="8" fill="#FFA500">R{vertex.fradius:.0f}</text>')

        # 添加网格线
        grid_step = 50  # 网格间距

        # 垂直网格线
        for i in range(margin, svg_width - margin + 1, grid_step):
            svg_lines.append(f'<line opacity="0.1" stroke="#000000" stroke-width="1" x1="{i}" y1="{svg_height - margin}" x2="{i}" y2="{margin}"/>')

        # 水平网格线
        for i in range(margin, svg_height - margin + 1, grid_step):
            svg_lines.append(f'<line opacity="0.1" stroke="#000000" stroke-width="1" x1="{margin}" y1="{i}" x2="{svg_width - margin}" y2="{i}"/>')

        # 添加坐标轴标签
        svg_lines.extend([
            f'<text x="20" y="{svg_height//2}" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="10" opacity="1" fill="#000000" transform="rotate(270, 20, {svg_height//2})">',
            'Y (mm)',
            '</text>',
            f'<text x="{svg_width//2}" y="{svg_height - 20}" dy="-0.5ex" text-anchor="middle" font-family="sans-serif" font-size="10" opacity="1" fill="#000000">',
            'X (mm)',
            '</text>',
        ])

        # 添加主要网格线（更粗）
        major_step = 200
        for i in range(margin, svg_width - margin + 1, major_step):
            svg_lines.append(f'<line opacity="0.2" stroke="#000000" stroke-width="1" x1="{i}" y1="{svg_height - margin}" x2="{i}" y2="{margin}"/>')

        for i in range(margin, svg_height - margin + 1, major_step):
            svg_lines.append(f'<line opacity="0.2" stroke="#000000" stroke-width="1" x1="{margin}" y1="{i}" x2="{svg_width - margin}" y2="{i}"/>')

        # 添加坐标轴
        svg_lines.extend([
            f'<polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="{margin-1},{margin} {margin-1},{svg_height - margin} "/>',
            f'<polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="{margin},{svg_height - margin + 1} {svg_width - margin},{svg_height - margin + 1} "/>',
        ])

        # 添加刻度标签
        num_ticks = 5
        for i in range(num_ticks + 1):
            # Y轴刻度
            y_pos = margin + i * (svg_height - 2 * margin) / num_ticks
            y_value = max_y - i * (max_y - min_y) / num_ticks
            svg_lines.extend([
                f'<text x="{margin - 10}" y="{y_pos}" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="10" opacity="1" fill="#000000">',
                f'{y_value:.1f}',
                '</text>',
                f'<polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="{margin - 5},{y_pos} {margin},{y_pos} "/>',
            ])

            # X轴刻度
            x_pos = margin + i * (svg_width - 2 * margin) / num_ticks
            x_value = min_x + i * (max_x - min_x) / num_ticks
            svg_lines.extend([
                f'<text x="{x_pos}" y="{svg_height - margin + 10}" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="10" opacity="1" fill="#000000">',
                f'{x_value:.1f}',
                '</text>',
                f'<polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="{x_pos},{svg_height - margin} {x_pos},{svg_height - margin + 5} "/>',
            ])

        # 添加右下角坐标表格
        table_width = 280
        table_height = min(400, len(processed_vertices) * 12 + 40)  # 限制最大高度
        table_x = svg_width - table_width - 10
        table_y = svg_height - table_height - 10

        # 表格背景
        svg_lines.append(f'<rect x="{table_x}" y="{table_y}" width="{table_width}" height="{table_height}" fill="white" stroke="#333" stroke-width="1" opacity="0.95" rx="5"/>')

        # 表格标题
        svg_lines.append(f'<text x="{table_x + table_width//2}" y="{table_y + 15}" text-anchor="middle" font-family="Arial" font-size="12" font-weight="bold" fill="#333">顶点坐标表</text>')

        # 表头
        header_y = table_y + 30
        svg_lines.append(f'<text x="{table_x + 10}" y="{header_y}" font-family="Arial" font-size="10" font-weight="bold" fill="#666">序号</text>')
        svg_lines.append(f'<text x="{table_x + 50}" y="{header_y}" font-family="Arial" font-size="10" font-weight="bold" fill="#666">X (mm)</text>')
        svg_lines.append(f'<text x="{table_x + 150}" y="{header_y}" font-family="Arial" font-size="10" font-weight="bold" fill="#666">Y (mm)</text>')

        # 分隔线
        svg_lines.append(f'<line x1="{table_x + 5}" y1="{header_y + 3}" x2="{table_x + table_width - 5}" y2="{header_y + 3}" stroke="#ccc" stroke-width="1"/>')

        # 坐标数据（限制显示数量，避免表格过长）
        max_display = min(len(processed_vertices), 30)  # 最多显示30个顶点
        for i in range(max_display):
            vertex = processed_vertices[i]
            row_y = header_y + 15 + i * 12

            # 序号
            svg_lines.append(f'<text x="{table_x + 15}" y="{row_y}" text-anchor="middle" font-family="Arial" font-size="9" fill="#333">{i}</text>')
            # X坐标
            svg_lines.append(f'<text x="{table_x + 55}" y="{row_y}" font-family="Arial" font-size="9" fill="#333">{vertex.x:.2f}</text>')
            # Y坐标
            svg_lines.append(f'<text x="{table_x + 155}" y="{row_y}" font-family="Arial" font-size="9" fill="#333">{vertex.y:.2f}</text>')

        # 如果顶点数超过显示限制，添加省略提示
        if len(processed_vertices) > max_display:
            remaining = len(processed_vertices) - max_display
            ellipsis_y = header_y + 15 + max_display * 12
            svg_lines.append(f'<text x="{table_x + table_width//2}" y="{ellipsis_y}" text-anchor="middle" font-family="Arial" font-size="9" fill="#999">... 还有{remaining}个顶点</text>')

        svg_lines.append('</svg>')

        svg_content = '\n'.join(svg_lines)

        # 保存到文件
        if filename:
            try:
                with open(filename, 'w', encoding='utf-8') as f:
                    f.write(svg_content)
                print(f"SVG已保存到: {filename}")
            except Exception as e:
                print(f"保存SVG文件时出错: {e}")

        return svg_content

    def add_path_arrows_and_labels(self, svg_lines: List[str], vertices: List[Vertex], transform_x, transform_y, is_open_path: bool):
        """添加路径箭头和文字标注"""
        n = len(vertices)
        if n < 2:
            return

        # 为每个线段添加箭头和标注
        for i in range(n - 1):
            current_vertex = vertices[i]
            next_vertex = vertices[i + 1]

            # 转换坐标
            x1 = transform_x(current_vertex.x)
            y1 = transform_y(current_vertex.y)
            x2 = transform_x(next_vertex.x)
            y2 = transform_y(next_vertex.y)

            # 检查是否是圆弧
            has_fradius = hasattr(current_vertex, 'fradius') and current_vertex.fradius and current_vertex.fradius > 0

            # 计算线段中点
            mid_x = (x1 + x2) / 2
            mid_y = (y1 + y2) / 2

            # 计算线段方向
            dx = x2 - x1
            dy = y2 - y1
            length = (dx*dx + dy*dy)**0.5

            if length > 0:
                # 单位方向向量
                unit_x = dx / length
                unit_y = dy / length

                # 箭头位置（线段的3/4处）
                arrow_ratio = 0.75
                arrow_x = x1 + dx * arrow_ratio
                arrow_y = y1 + dy * arrow_ratio

                # 添加箭头线段（更细的线条）
                if has_fradius:
                    # 圆弧用红色箭头
                    svg_lines.append(f'<line x1="{x1:.1f}" y1="{y1:.1f}" x2="{x2:.1f}" y2="{y2:.1f}" stroke="#FF0066" stroke-width="1.5" marker-end="url(#arrowhead-arc)" opacity="0.7"/>')
                    segment_type = "A"
                    color = "#FF0066"
                else:
                    # 直线用橙色箭头
                    svg_lines.append(f'<line x1="{x1:.1f}" y1="{y1:.1f}" x2="{x2:.1f}" y2="{y2:.1f}" stroke="#FF6600" stroke-width="1.5" marker-end="url(#arrowhead)" opacity="0.7"/>')
                    segment_type = "L"
                    color = "#FF6600"

                # 计算文字位置（线段中点偏移）
                # 垂直于线段方向的偏移，减小偏移距离
                perp_x = -unit_y * 12  # 垂直方向偏移12像素（减少了3像素）
                perp_y = unit_x * 12

                text_x = mid_x + perp_x
                text_y = mid_y + perp_y

                # 添加路径标注文字（更小的文字）
                label_text = f"{i}({segment_type})→{i+1}"

                # 文字背景（更小的背景框）
                svg_lines.append(f'<rect x="{text_x-12:.1f}" y="{text_y-6:.1f}" width="24" height="10" fill="white" stroke="{color}" stroke-width="0.3" opacity="0.85" rx="1"/>')

                # 文字（更小的字体）
                svg_lines.append(f'<text x="{text_x:.1f}" y="{text_y:.1f}" text-anchor="middle" font-family="Arial" font-size="7" font-weight="bold" fill="{color}">{label_text}</text>')

        # 如果是闭合路径，添加从最后一个顶点回到起点的箭头
        if not is_open_path and n > 2:
            last_vertex = vertices[-1]
            first_vertex = vertices[0]

            x1 = transform_x(last_vertex.x)
            y1 = transform_y(last_vertex.y)
            x2 = transform_x(first_vertex.x)
            y2 = transform_y(first_vertex.y)

            # 计算距离，只有当距离足够大时才添加闭合箭头
            distance = ((x2-x1)**2 + (y2-y1)**2)**0.5
            if distance > 10:  # 只有当距离大于10像素时才显示闭合箭头
                mid_x = (x1 + x2) / 2
                mid_y = (y1 + y2) / 2

                dx = x2 - x1
                dy = y2 - y1
                length = (dx*dx + dy*dy)**0.5

                if length > 0:
                    unit_x = dx / length
                    unit_y = dy / length

                    # 闭合线段用绿色箭头（更细的线条）
                    svg_lines.append(f'<line x1="{x1:.1f}" y1="{y1:.1f}" x2="{x2:.1f}" y2="{y2:.1f}" stroke="#00AA00" stroke-width="1.5" marker-end="url(#arrowhead)" opacity="0.7" stroke-dasharray="3,3"/>')

                    # 文字位置（减小偏移）
                    perp_x = -unit_y * 12
                    perp_y = unit_x * 12
                    text_x = mid_x + perp_x
                    text_y = mid_y + perp_y

                    # 闭合标注（更小的文字）
                    label_text = f"{n-1}(L)→0"
                    svg_lines.append(f'<rect x="{text_x-12:.1f}" y="{text_y-6:.1f}" width="24" height="10" fill="white" stroke="#00AA00" stroke-width="0.3" opacity="0.85" rx="1"/>')
                    svg_lines.append(f'<text x="{text_x:.1f}" y="{text_y:.1f}" text-anchor="middle" font-family="Arial" font-size="7" font-weight="bold" fill="#00AA00">{label_text}</text>')

def process_single_file(processor, file_path, output_dir):
    """处理单个文件"""
    import os

    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            content = f.read()
        print(f"读取文件: {file_path}")
    except Exception as e:
        print(f"读取文件 {file_path} 时出错: {e}")
        return None

    # 解析PLOOP数据
    ploops = processor.parse_file(content)

    if len(ploops) == 0:
        print(f"  警告: {file_path} 中没有找到任何有效的PLOOP数据")
        return None

    # 处理每个PLOOP
    results = []
    for ploop in ploops:
        print(f"  处理PLOOP: {ploop.name}")

        # 处理顶点
        processed_vertices = processor.process_ploop(ploop)

        # 检查FRADIUS信息
        fradius_count = sum(1 for v in processed_vertices if v.fradius)
        print(f"    顶点: {len(ploop.vertices)} → {len(processed_vertices)}, FRADIUS: {fradius_count}")

        # 生成SVG文件名
        case_name = ploop.name.replace('/', '_').replace('-', '_').lower()
        svg_filename = os.path.join(output_dir, f"{case_name}_profile.svg")

        # 生成SVG
        processor.generate_svg_with_arcs(ploop, processed_vertices, svg_filename)

        results.append({
            'ploop': ploop,
            'processed_vertices': processed_vertices,
            'svg_file': svg_filename,
            'fradius_count': fradius_count
        })

    return results

def batch_process_test_data():
    """批量处理test-data目录中的所有文件"""
    import os
    import glob

    processor = PLoopProcessor()

    # 确定目录路径
    current_dir = os.path.dirname(os.path.abspath(__file__))
    test_data_dir = os.path.join(current_dir, "test-data")
    output_dir = os.path.join(current_dir, "python-svg")

    # 确保输出目录存在
    os.makedirs(output_dir, exist_ok=True)

    # 查找所有.txt文件
    pattern = os.path.join(test_data_dir, "*.txt")
    txt_files = glob.glob(pattern)

    if not txt_files:
        print(f"在 {test_data_dir} 中没有找到任何.txt文件")
        return

    print(f"找到 {len(txt_files)} 个数据文件")
    print("="*80)

    all_results = []

    # 处理每个文件
    for file_path in sorted(txt_files):
        filename = os.path.basename(file_path)
        print(f"\n处理文件: {filename}")
        print("-" * 60)

        results = process_single_file(processor, file_path, output_dir)
        if results:
            all_results.extend(results)

    # 生成汇总报告
    print("\n" + "="*80)
    print("批量处理完成汇总")
    print("="*80)
    print(f"总共处理文件: {len(txt_files)}")
    print(f"总共生成PLOOP: {len(all_results)}")

    # 统计信息
    total_original_vertices = sum(len(r['ploop'].vertices) for r in all_results)
    total_processed_vertices = sum(len(r['processed_vertices']) for r in all_results)
    total_fradius = sum(r['fradius_count'] for r in all_results)

    print(f"总顶点数: {total_original_vertices} → {total_processed_vertices}")
    print(f"总FRADIUS数: {total_fradius}")

    # 详细列表
    print(f"\n生成的SVG文件:")
    for i, result in enumerate(all_results, 1):
        ploop = result['ploop']
        svg_file = os.path.basename(result['svg_file'])
        print(f"  {i:2d}. {svg_file} - {ploop.name} (高度: {ploop.height}mm)")

    print(f"\n所有SVG文件已保存到: {output_dir}")

def main(target_case=None):
    """主函数 - 兼容原有接口"""
    if target_case is None:
        # 如果没有指定案例，执行批量处理
        batch_process_test_data()
        return

    processor = PLoopProcessor()

    # 读取文件
    try:
        with open('717.txt', 'r', encoding='utf-8') as f:
            content = f.read()
        print(f"文件读取成功，内容长度: {len(content)} 字符")
    except FileNotFoundError:
        print("错误: 找不到文件 717.txt")
        return
    except Exception as e:
        print(f"读取文件时出错: {e}")
        return

    # 解析PLOOP数据
    print("\n开始解析PLOOP数据...")
    ploops = processor.parse_file(content)
    print(f"\n解析完成，发现 {len(ploops)} 个PLOOP")

    if len(ploops) == 0:
        print("警告: 没有找到任何有效的PLOOP数据")
        return

    # 查找指定的案例
    target_ploop = None
    for ploop in ploops:
        if target_case in ploop.name:
            target_ploop = ploop
            break

    if target_ploop is None:
        print(f"错误: 没有找到 {target_case} PLOOP")
        print("可用的案例:")
        for ploop in ploops:
            print(f"  - {ploop.name}")
        return

    print(f"\n找到{target_case}: {target_ploop}")
    print("="*80)

    # 处理指定案例
    processed_vertices = processor.process_ploop(target_ploop)

    # 检查FRADIUS信息是否正确保留
    fradius_count = sum(1 for v in processed_vertices if v.fradius)
    print(f"处理完成: {len(processed_vertices)} 个顶点，其中 {fradius_count} 个圆弧顶点")

    # 生成详细报告
    report = processor.generate_profile_report(target_ploop, processed_vertices)
    print(report)

    # 生成SVG
    print("\n生成SVG可视化...")
    import os

    # 确保python-svg目录存在（在项目根目录下）
    current_dir = os.path.dirname(os.path.abspath(__file__))
    # 如果当前在reverse-mcp目录下，则使用当前目录；否则找到reverse-mcp目录
    if os.path.basename(current_dir) == "reverse-mcp":
        project_root = current_dir
    else:
        project_root = os.path.dirname(current_dir)

    svg_dir = os.path.join(project_root, "python-svg")
    os.makedirs(svg_dir, exist_ok=True)

    # 动态生成文件名
    case_name = target_case.lower()
    svg_filename = os.path.join(svg_dir, f"{case_name}_profile_with_arcs.svg")
    processor.generate_svg_with_arcs(target_ploop, processed_vertices, svg_filename)

    print(f"\n{target_case}分析完成！")
    print(f"- 原始顶点数: {len(target_ploop.vertices)}")
    print(f"- 处理后顶点数: {len(processed_vertices)}")
    print(f"- FRADIUS数量: {sum(1 for v in processed_vertices if v.fradius)}")
    print(f"- SVG文件: {svg_filename}")

    # 显示FRADIUS详情
    fradius_vertices = [v for v in target_ploop.vertices if v.fradius]
    if fradius_vertices:
        print(f"\nFRADIUS详情:")
        for i, v in enumerate(fradius_vertices):
            print(f"  {i+1}. 位置: ({v.x:.2f}, {v.y:.2f}) - 半径: {v.fradius:.2f}mm")

if __name__ == "__main__":
    import sys

    # 检查命令行参数
    if len(sys.argv) > 1:
        target_case = sys.argv[1].upper()
        if not target_case.startswith('K'):
            target_case = 'K' + target_case
        main(target_case)
    else:
        print("开始批量处理test-data目录中的所有数据文件...")
        print("如需处理特定案例，请使用: python ploop_processor_fixed.py <案例编号>")
        print("例如: python ploop_processor_fixed.py K718")
        print("")
        main()  # 执行批量处理